package com.chen.magnetic;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

@SuppressLint("DrawAllocation")
public class MageticImageView extends ImageView {

	private static final String	TAG				= MageticImageView.class
														.getSimpleName();
	private boolean				onAnimation		= true;
	private int					rotateDegree	= 10;						// 偏转的角度

	private boolean				isFirst			= true;
	private float				minScale		= 0.90f;					// 控制缩放到的最小比例
	private int					vWidth;									// 图片的宽度
	private int					vHeight;									// 图片的高度
	private boolean				isFinish		= true, isActionMove = false,
			isScale = false;
	private Camera				camera;

	boolean						XbigY			= false;
	float						RolateX			= 0;						// 相对于图片中心，横坐标的偏移量
	float						RolateY			= 0;						// 相对于图片中心，纵坐标的偏移量

	OnViewClick					onclick			= null;

	public MageticImageView(Context context) {
		super(context);
		camera = new Camera();
	}

	public MageticImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		camera = new Camera();
	}

	/**
	 * 控制动画的开关
	 * 
	 * @param bSwitch
	 */
	public void SetAnimationOnOff(boolean bSwitch) {
		onAnimation = bSwitch;
	}

	public void setOnClickIntent(OnViewClick onclick) {
		this.onclick = onclick;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 首次进入时对图片进行初始化
		if (isFirst) {
			isFirst = false;
			init();
		}
		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
				| Paint.FILTER_BITMAP_FLAG));
	}

	/**
	 * 初始化图片
	 */
	public void init() {
		// 去除边距，计算图片的实际宽高
		vWidth = getWidth() - getPaddingLeft() - getPaddingRight();
		vHeight = getHeight() - getPaddingTop() - getPaddingBottom();
		Drawable drawable = getDrawable();
		BitmapDrawable bd = (BitmapDrawable) drawable;
		bd.setAntiAlias(true);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);
		// 当动画正在执行中，则不再响应触摸事件
		if (!onAnimation)
			return true;

		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			// x y 取的是图片上的相对坐标，而不是屏幕上的绝对坐标
			float X = event.getX();
			float Y = event.getY();
			// Logger.i(TAG, "x = " + X + ",y = " + Y);
			// Logger.i(TAG, "vWidth = " + vWidth + ",vHeight = " + vHeight);
			// 以图片的中点为基准，计算点击时的偏移量
			RolateX = vWidth / 2 - X;
			RolateY = vHeight / 2 - Y;
			// Logger.i(TAG, "RolateX = " + RolateX + ",RolateY = " + RolateY);
			// 判断点击在图片上时，相对于中心点，x和y的便宜量哪个更大
			XbigY = Math.abs(RolateX) > Math.abs(RolateY) ? true : false;

			// 点击时的x坐标值超过图片宽度的1/3且小于2/3，y坐标同上时，才会进行按比例缩放
			// 此时点击位置在图片的中间位置，所以不倾斜
			isScale = X > vWidth / 3 && X < vWidth * 2 / 3 && Y > vHeight / 3
					&& Y < vHeight * 2 / 3;
			isActionMove = false;

			if (isScale) {
				// 点击了中间部分，则使用handler进行控制
				handler.sendEmptyMessage(1);
			} else {
				// 点击了左右的边缘部分，则使用rolateHandler进行控制
				rolateHandler.sendEmptyMessage(1);
			}
			break;
		case MotionEvent.ACTION_MOVE:
			float x = event.getX();
			float y = event.getY();
			if (x > vWidth || y > vHeight || x < 0 || y < 0) {
				isActionMove = true;
			} else {
				isActionMove = false;
			}

			break;
		case MotionEvent.ACTION_UP:
			if (isScale) {
				handler.sendEmptyMessage(6);
			} else {
				rolateHandler.sendEmptyMessage(6);
			}
			break;
		}
		return true;
	}

	public interface OnViewClick {
		public void onClick();
	}

	/** 当按压的位置不在中间位置时，使用该Handler */
	private Handler	rolateHandler	= new Handler() {
										private Matrix	matrix	= new Matrix();
										private float	count	= 0;

										@Override
										public void handleMessage(Message msg) {
											super.handleMessage(msg);
											int what = msg.what;
											// Logger.i(TAG,
											// "rolateHandler what = "
											// + what);
											matrix.set(getImageMatrix());
											switch (msg.what) {
											case 1:
												count = 0;
												BeginRolate(matrix,
														(XbigY ? count : 0),
														(XbigY ? 0 : count));
												rolateHandler
														.sendEmptyMessage(2);
												break;
											case 2:
												BeginRolate(matrix,
														(XbigY ? count : 0),
														(XbigY ? 0 : count));
												if (count < getDegree()) {
													rolateHandler
															.sendEmptyMessage(2);
												} else {
													isFinish = true;
												}
												count++;
												count++;
												break;
											case 3:
												BeginRolate(matrix,
														(XbigY ? count : 0),
														(XbigY ? 0 : count));
												if (count > 0) {
													rolateHandler
															.sendEmptyMessage(3);
												} else {
													isFinish = true;
													if (!isActionMove
															&& onclick != null) {
														onclick.onClick();
													}
												}
												count--;
												count--;
												break;
											case 6:
												count = getDegree();
												BeginRolate(matrix,
														(XbigY ? count : 0),
														(XbigY ? 0 : count));
												rolateHandler
														.sendEmptyMessage(3);
												break;
											}
										}
									};

	private synchronized void BeginRolate(Matrix matrix, float rolateX,
			float rolateY) {
		// Bitmap bm = getImageBitmap();
		int scaleX = (int) (vWidth * 0.5f);
		int scaleY = (int) (vHeight * 0.5f);
		camera.save();
		camera.rotateX(RolateY > 0 ? rolateY : -rolateY);
		camera.rotateY(RolateX < 0 ? rolateX : -rolateX);
		camera.getMatrix(matrix);
		camera.restore();
		// 控制中心点
		if (RolateX > 0 && rolateX != 0) {
			matrix.preTranslate(-vWidth, -scaleY);
			matrix.postTranslate(vWidth, scaleY);
		} else if (RolateY > 0 && rolateY != 0) {
			matrix.preTranslate(-scaleX, -vHeight);
			matrix.postTranslate(scaleX, vHeight);
		} else if (RolateX < 0 && rolateX != 0) {
			matrix.preTranslate(-0, -scaleY);
			matrix.postTranslate(0, scaleY);
		} else if (RolateY < 0 && rolateY != 0) {
			matrix.preTranslate(-scaleX, -0);
			matrix.postTranslate(scaleX, 0);
		}
		setImageMatrix(matrix);
	}

	/** 当按压的位置在图片的中间位置时，使用该Handler */
	private Handler	handler	= new Handler() {
								private Matrix	matrix	= new Matrix();
								private float	s;
								int				count	= 0;
								private  int lCount = 0;
								private  int mCount = 0;

								@Override
								public void handleMessage(Message msg) {
									super.handleMessage(msg);
									int what = msg.what;
//									Logger.d(TAG, "handler what = " + what);
									matrix.set(getImageMatrix());
									switch (msg.what) {
									case 1:
										// 点击图片的中间位置时，执行该分支
										if (!isFinish) {
											// 未结束，则不响应
											return;
										} else {
											// 已结束，则执行该分支
											isFinish = false;
											count = 0;
											//初始化要缩小的比例
											s = (float) Math.sqrt(Math
													.sqrt(minScale));
											BeginScale(matrix, s);
											handler.sendEmptyMessage(2);
											Logger.v(TAG, "变大次数="+lCount++);
										}
										break;
									case 2:
										BeginScale(matrix, s);
										// 控制缩放的次数
										if (count < 4) {
											handler.sendEmptyMessage(2);
										} else {
											isFinish = true;
											if (!isActionMove
													&& onclick != null) {
												onclick.onClick();
											}
										}
										count++;
										break;
									case 6:
										if (!isFinish) {
											// 未结束，则进入等待状态
											handler.sendEmptyMessage(6);
											Logger.i(TAG, "变小次数="+mCount++);
										} else {
											isFinish = false;
											count = 0;
											//初始化要放大的比例
											s = (float) Math.sqrt(Math
													.sqrt(1.0f / minScale));
											BeginScale(matrix, s);
											handler.sendEmptyMessage(2);
										}
										break;
									}
								}
							};

	/**
	 * 开始进行渐变缩放
	 * 
	 * @param matrix
	 *            坐标变换矩阵
	 * @param scale
	 *            缩放比例
	 */
	private synchronized void BeginScale(Matrix matrix, float scale) {
		int scaleX = (int) (vWidth * 0.5f);
		int scaleY = (int) (vHeight * 0.5f);
		// 使用该方法，实现渐变缩放
		matrix.postScale(scale, scale, scaleX, scaleY);
		setImageMatrix(matrix);
	}

	public int getDegree() {
		return rotateDegree;
	}

	public void setDegree(int degree) {
		rotateDegree = degree;
	}

	public float getScale() {
		return minScale;
	}

	public void setScale(float scale) {
		minScale = scale;
	}
}
